package fregat.microchip.usb;

import org.apache.commons.cli.ParseException;

import fregat.application.context.IApplicationContext;
import fregat.base.util.*;
import fregat.microchip.usb.device.*;
import fregat.usb.application.context.ApplicationContext;
import fregat.usb.application.context.arguments.ApplicationArguments;
import fregat.usb.configprovider.ConfigProviderFactory;
import fregat.usb.configprovider.ConfigProviderType;
import fregat.usb.configprovider.IConfigProvider;
import fregat.usb.configprovider.IConfigProviderFactory;
import fregat.usb.configprovider.ConfigProviderType;
import fregat.usb.configprovider.IConfiguration;

public class jusb {

static private jusb			instance = null;
public static final byte ADC_QUERY = 1;
public static final byte CONFIG_QUERY = 2;
public static final byte CONFIG_CNTRL = 3;

public Logger				log;
public IConfigProviderFactory	configFactory;
public native void			readConfiguration ();
public native usb_device	findDevice (short vendor_id, short product_id) throws deviceNotFoundException;
public native int			openDevice (usb_device d);
public native int			writeDevice (usb_device d, byte[] wbuffer);
public native byte []		readDevice (usb_device d);


public void debug (String str) {
	log.debug(str);
}

public void info (String str) {
	log.info(str);
}

public void error (String str) {
	log.error(str);
}

public void shutdown () {
	Logger.shutdownAll();
}

public static jusb createInstance ()
{
	if (instance == null) {
		instance = new jusb ();
		instance.readConfiguration();
	}
	return instance;
}

private jusb () {
	log = Logger.getCategory("DEBUG");
	log.setOut(System.out);
	log.setConsoleLevel(Logger.NOTE);
	configFactory = new ConfigProviderFactory();
}

//static {
//	System.loadLibrary("libusb0"); // don't need to load here, will be loaded from windows/system32 folder
////	System.loadLibrary("libjusbdll");
//}

public static void main(String[] args) {
	jusb usb = jusb.createInstance();
	
	
//	typedef struct CONFIG_OPTIONS_T
//	{
//		T0CON_T			t0con;	T1CON_T			t1con;
//		TMR0L_T			tmr0l;	TMR0H_T			tmr0h;
//		TMR1L_T			tmr1l;	TMR1H_T			tmr1h;
//		ADCON0_T		adcon0;	ADCON1_T		adcon1;
//		ADCON2_T		adcon2;
//	} CONFIG_OPTIONS;

	
	try {
		IApplicationContext appcontext = new ApplicationContext(args);
		IConfigProvider config_provider = usb.configFactory.createConfigProvider(appcontext, ConfigProviderType.DATABASE);
		IConfiguration configuration = config_provider.getConfiguration();
		
		usb_device ud = usb.findDevice(configuration.getVendorId()/*(short)0x4d8*/, configuration.getProductId()/*(short)0xc*/);
		int res = ud.open();
		usb.info("Device is open witd result = "+res);
		//byte conf_command[] = {0x3, (byte)0x98, (byte)0xfe, 0x0, 0xe, (byte)0xff, (byte)0xe0, 0x0, 0x0};
//		configCommand cc = new configCommand();
//		cc.setT0CON((byte)0x97);
//		cc.setT1CON((byte)0xfe);
//		cc.setTimer0((short)0xb3b4);
//		cc.setTimer1((short)0);
//		cc.setADCON0((byte)0);
//		cc.setADCON1((byte)0);
//		cc.setADCON2((byte)0xe);
//		cc.setSingleMode();
//		
//		ud.write (cc.toByteArray());
//		
//		byte conf_data[] = ud.read();
//		cc.enableADC();
//		ud.write (cc.toByteArray());
//		conf_data = ud.read();
//		
//		byte conf_command[] = cc.toByteArray();
//		conf_command[0] = jusb.ADC_QUERY;
//		conf_command[1] = (byte)0x1;
//		ud.write(conf_command);
//		conf_data = ud.read();
//		ud.write(conf_command);
//		conf_data = ud.read();
//		
//		while (true) {
//			byte chunks_command[] = {0x1};
//			ud.write(chunks_command);
//			byte data [] = ud.read();
//			Thread.sleep(1000);
//		}
	}
//	catch (InterruptedException intex) {
//		
//	}
	catch (IConfigProviderFactory.UnknownProviderException upex) {
		usb.info(upex.toString());
	}
	catch (deviceNotFoundException dnfex) {
		usb.info(dnfex.toString());
	}
	usb.shutdown();
}
}
